﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

namespace FieldTools.Util
{
    /// <summary>
    /// 拓展类
    /// </summary>
    public static class JsonExtention
    {
        static JsonExtention()
        {
            JsonConvert.DefaultSettings = () => DefaultJsonSetting;
        }
        public static JsonSerializerSettings DefaultJsonSetting = new JsonSerializerSettings
        {
            ContractResolver = new DefaultContractResolver(),
            DateFormatHandling = DateFormatHandling.MicrosoftDateFormat,
            DateFormatString = "yyyy-MM-dd HH:mm:ss.fff"
        };

        /// <summary>
        /// 将对象序列化成Json字符串
        /// </summary>
        /// <param name="obj">需要序列化的对象</param>
        /// <returns></returns>
        public static string ToJson(this object obj)
        {
            return JsonConvert.SerializeObject(obj);
        }

        /// <summary>
        /// 将对象序列化成Json字符串
        /// </summary>
        /// <param name="obj">需要序列化的对象</param>
        /// <param name="toLower">小驼峰</param>
        /// <returns></returns>
        public static string ToJson(this object obj, bool toLower = false, NullValueHandling nullValueHandling = NullValueHandling.Ignore)
        {
            if (toLower)
            {
                var setting = new JsonSerializerSettings
                {
                    ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver(),
                    NullValueHandling = nullValueHandling,
                };
                return JsonConvert.SerializeObject(obj, Formatting.None, setting);
            }
            return JsonConvert.SerializeObject(obj);
        }

        /// <summary>
        /// 将Json字符串反序列化为对象
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="jsonStr">Json字符串</param>
        /// <returns></returns>
        public static T ToObject<T>(this string jsonStr)
        {
            return JsonConvert.DeserializeObject<T>(jsonStr);
        }

        /// <summary>
        /// 将Json字符串反序列化为对象
        /// </summary>
        /// <param name="jsonStr">json字符串</param>
        /// <param name="type">对象类型</param>
        /// <returns></returns>
        public static object ToObject(this string jsonStr, Type type)
        {
            return JsonConvert.DeserializeObject(jsonStr, type);
        }
        public static void UpdateAppsettingJson(string str, string jsonfile = "appsettings.json")
        {
            try
            {
                if (File.Exists(jsonfile))
                {
                    File.WriteAllText(jsonfile, str);//将内容写进jon文件中
                }
                else
                {

                }
            }
            catch (Exception ex)
            {
                //throw;
            }
        }
        /// <summary>
		/// 更新json文件中指定字段，只能是字段，不能是对象
		/// </summary>
		/// <param name="fieldName"></param>
		/// <param name="value"></param>
		/// <param name="jsonfile"></param>
		public static void UpdateAppsettingJson(string fieldName, string value, string jsonfile = "appsettings.json")
        {
            if (fieldName == null || fieldName == "" || value == null) return;
            try
            {
                if (File.Exists(jsonfile))
                {
                    string jsonString = File.ReadAllText(jsonfile, Encoding.Default);//读取文件
                    JObject jobject = JObject.Parse(jsonString);//解析成json
                    jobject[fieldName] = value;//替换
                    string convertString = Convert.ToString(jobject);//将json装换为string
                    File.WriteAllText(jsonfile, convertString);//将内容写进jon文件中
                }
                else
                {

                }
            }
            catch (Exception ex)
            {
                //throw;
            }
        }
        /// <summary>
        /// 获取json文件转字符串
        /// </summary>
        /// <param name="jsonfile"></param>
        /// <returns></returns>
        public static string GetAppsettingJson(string jsonfile = "appsettings.json")
        {
            try
            {
                string jsonString = File.ReadAllText(jsonfile, Encoding.GetEncoding("utf-8"));//读取文件

                JObject jobject = JObject.Parse(jsonString);//解析成json
                return jobject?.ToString();
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 获取json文件中指定字段的数据
        /// </summary>
        /// <param name="fieldName"></param>
        /// <param name="jsonfile"></param>
        /// <returns></returns>
        public static string GetAppsettingJson(string fieldName, string jsonfile = "appsettings.json")
        {
            if (fieldName == null || fieldName == "") return "";

            try
            {
                string jsonString = File.ReadAllText(jsonfile, Encoding.GetEncoding("utf-8"));//读取文件

                JObject jobject = JObject.Parse(jsonString);//解析成json
                return jobject[fieldName]?.ToString();
            }
            catch (Exception)
            {

                throw;
            }
        }

        /// <summary>
        /// 将json字符串反序列化为字典类型
        /// </summary>
        /// <typeparam name="TKey">字典key</typeparam>
        /// <typeparam name="TValue">字典value</typeparam>
        /// <param name="jsonStr">json字符串</param>
        /// <returns>字典数据</returns>
        public static Dictionary<TKey, TValue> DeserializeStringToDictionary<TKey, TValue>(string jsonStr)
        {
            if (string.IsNullOrEmpty(jsonStr))
                return new Dictionary<TKey, TValue>();

            Dictionary<TKey, TValue> jsonDict = JsonConvert.DeserializeObject<Dictionary<TKey, TValue>>(jsonStr);

            return jsonDict;

        }
        /// <summary>
        /// json字符串转对象数组，仅支持一层
        /// </summary>
        /// <param name="jsonStr"></param>
        /// <returns></returns>
        public static object[] DeserializeStringToObjectArray(string jsonStr)
        {
            if (string.IsNullOrEmpty(jsonStr))
                return null;
            var objs = new List<object>();
            try
            {
                Dictionary<string, object> dict = DeserializeStringToDictionary<string, object>(jsonStr);
                dict.ForEach(v =>
                {
                    objs.Add(v.Value);
                });
            }
            catch (Exception ex)
            {
                objs.Add(ex);
            }

            return objs?.ToArray() ?? null;

        }


        public static List<object> JsonToObjectList(string jsonStr)
        {
            var dict = DeserializeStringToDictionary<string, object>(jsonStr);
            List<object> res = new();
            var temp = dict;

            foreach (var item in temp)
            {
                if (dict[item.Key] == null)
                {
                    res.Add(null);
                    continue;
                }
                Type type = dict[item.Key].GetType();
                //值类型
                if (type.IsValueType && !type.IsClass)
                {
                    res.Add(dict[item.Key]);
                }
                //string类型
                else if (type == typeof(string))
                {
                    res.Add(dict[item.Key]);
                }
                else
                {
                    var a1 = dict[item.Key].ObjectUnboxing();
                    var a2 = a1.DicToObject<object>();
                    res.Add(a2);
                }
            }
            //dict = dict.ToDictionary(x => x.Key, x => x.Value.GetType().IsValueType ? x : x.Value.ObjectUnboxing().DicToObject<object>());
            return res;
        }
        /// <summary>
        /// json字符串格式化
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string FormatJsonString(this string str)
        {
            if (str.IsNullOrEmpty()) return "";
            try
            {
                //格式化json字符串
                JsonSerializer serializer = new JsonSerializer();
                TextReader tr = new StringReader(str);
                JsonTextReader jtr = new JsonTextReader(tr);
                object obj = serializer.Deserialize(jtr);
                if (obj != null)
                {
                    StringWriter textWriter = new StringWriter();
                    JsonTextWriter jsonWriter = new JsonTextWriter(textWriter)
                    {
                        Formatting = Formatting.Indented,
                        Indentation = 4,
                        IndentChar = ' '
                    };
                    serializer.Serialize(jsonWriter, obj);
                    return textWriter.ToString();
                }
                else
                {
                    return str;
                }
            }
            catch (Exception)
            {
                return str;
            }
           
        }
        /// <summary>
        /// 获取指定节点数据
        /// </summary>
        /// <param name="jsonStr"></param>
        /// <param name="nodePath">格式：["ce"][0]["ro"]</param>
        /// <returns></returns>
        public static string GetJsonNode(this string jsonStr, string nodePath)
        {
            if (nodePath.IsNullOrEmpty()) return jsonStr;
            JObject jobject = JObject.Parse(jsonStr);//解析成json
            //if(!jobject.HasValues)return "";
            Regex regex = new(@"(?i)(?<=\[)(.*?)(?=\])");
            var matches = regex.Matches(nodePath);
            JToken node = jobject;
            foreach (Match match in matches)
            {
                if (match.Success)
                {
                    var index = match.Value.TryToInt();
                    if(index != null)
                    {
                        node = node[index];
                    }
                    else
                    {
                        node = node[match.Value];
                    }
                    if (node == null) break;
                }
            }
            if(node == null)
            {
                return "未匹配到节点";
            }
            return node.ToString();
        }
    }
}
